﻿// -----------------------------------------------------------------------
// <copyright file="IMG_Transformations.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace ImageProcessing.IMG_Processor
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public static class IMG_Transformations
    {
        /// <summary>
        /// flips an image horizontally 
        /// </summary>
        /// <param name="img_Org"> the original image buffer</param>
        /// <returns>the flipped image buffer</returns>
        public static Entities.IMG_Image IMG_FlipHorizontal(Entities.IMG_Image img_Org)
        {
            try
            {
                int img_Width = img_Org.Width;
                int img_Height = img_Org.Height;
                Entities.IMG_Image img_FlippedImage = new Entities.IMG_Image(img_Width, img_Height);
                int img_XFront = 0;
                int img_XRear = img_Width - 1;
                for (int i = 0; i < img_Height; i++)
                {
                    while (img_XFront <= img_XRear)
                    {
                        img_FlippedImage[i, img_XRear] = img_Org[i, img_XFront];
                        img_FlippedImage[i, img_XFront] = img_Org[i, img_XRear];
                        img_XFront++;
                        img_XRear--;
                    }

                    img_XFront = 0;
                    img_XRear = img_Width - 1;
                }

                return img_FlippedImage;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// flips an image vertically 
        /// </summary>
        /// <param name="img_Org"> the original image buffer</param>
        /// <returns>the flipped image buffer</returns>
        public static Entities.IMG_Image IMG_FlipVertical(Entities.IMG_Image img_Org)
        {
            try
            {
                int img_Width = img_Org.Width;
                int img_Height = img_Org.Height;
                Entities.IMG_Image img_FlippedImage = new Entities.IMG_Image(img_Width, img_Height);
                int img_YFront = 0;
                int img_YRear = img_Height - 1;
                for (int i = 0; i < img_Width; i++)
                {
                    while (img_YFront < img_YRear)
                    {
                        img_FlippedImage[img_YRear, i] = img_Org[img_YFront, i];
                        img_FlippedImage[img_YFront, i] = img_Org[img_YRear, i];
                        img_YFront++;
                        img_YRear--;
                    }

                    img_YFront = 0;
                    img_YRear = img_Height - 1;
                }

                return img_FlippedImage;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// shear function in x direction
        /// </summary>
        /// <param name="img_Org">original image buffer</param>
        /// <param name="img_ShearScale">shear angle</param>
        /// <returns>sheared image buffer</returns>
        public static Entities.IMG_Image IMG_ShearX(Entities.IMG_Image img_Org, double img_ShearScale)
        {
            try
            {
                int img_Width = img_Org.Width;
                int img_Height = img_Org.Height;
                double img_CotanSHearAng = 1 / Math.Tan(img_ShearScale);
                int img_m = (int)(img_Width * img_CotanSHearAng);
                Entities.IMG_Image img_ShearedImage = new Entities.IMG_Image(img_Width + img_m, img_Height);
                for (int i = 0; i < img_Height; i++)
                {
                    for (int j = 0; j < img_Width; j++)
                    {
                        img_ShearedImage[i, j + (int)(img_CotanSHearAng * (img_Height - i))] = new Entities.Pixel(img_Org[i, j].Red, img_Org[i, j].Green, img_Org[i, j].Blue);
                    }
                }

                return img_ShearedImage;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// shear function in y direction
        /// </summary>
        /// <param name="img_Org">original image buffer</param>
        /// <param name="img_ShearScale">shear angle</param>
        /// <returns>sheared image buffer</returns>
        public static Entities.IMG_Image IMG_ShearY(Entities.IMG_Image img_Org, double img_ShearScale)
        {
            try
            {
                int img_Width = img_Org.Width;
                int img_Height = img_Org.Height;
                double img_CotanSHearAng = 1 / Math.Tan(img_ShearScale);
                int img_m = (int)(img_Width * img_CotanSHearAng);
                Entities.IMG_Image img_ShearedImage = new Entities.IMG_Image(img_Width, img_Height + img_m);
                for (int j = 0; j < img_Width; j++)
                {
                    for (int i = 0; i < img_Height; i++)
                    {
                        img_ShearedImage[i + (int)(img_CotanSHearAng * j), j] = img_Org[i, j];
                    }
                }

                return img_ShearedImage;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }
    }
}
